#region Using directives

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;

using Hanoi;
using Hanoi.Ui;
using Hanoi.Logic;

#endregion

namespace Hanoi
{
    /// <summary>
    /// Summary description for form.
    /// </summary>
    public class FormMain : System.Windows.Forms.Form
    {
        private MenuItem mnuNew;
        private MenuItem mnuMenu;
        private PictureBox pbGameBoard;
        private Label lblStat;
        private MenuItem mnuUndo;
        private MenuItem mnuNewGame;
        private MenuItem menuItem5;
        private MenuItem mnuAbout;
        private Timer tmr;
        private PictureBox pbResult;
        private ImageList ilPicturesUsed;
        private Panel pnInfo;
        /// <summary>
        /// Main menu for the form.
        /// </summary>
        private System.Windows.Forms.MainMenu mainMenu1;

        public FormMain(IGame rules, Form caller)
        {
            InitializeComponent();
            ResizeComponent();
            this.gameRules = rules;
            this._caller = caller;
            StartNewGame();
        }

        private void ResizeComponent()
        {
            pbGameBoard.Width = this.Width;
            pbGameBoard.Height = (this.Height - pnInfo.Height) * 90 / 100;

            pnInfo.Top = pbGameBoard.Height;
            pnInfo.Left = 0;
            pnInfo.Width = this.Width;
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            tmr.Enabled = false;
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain));
            this.mainMenu1 = new System.Windows.Forms.MainMenu();
            this.mnuNew = new System.Windows.Forms.MenuItem();
            this.mnuMenu = new System.Windows.Forms.MenuItem();
            this.mnuUndo = new System.Windows.Forms.MenuItem();
            this.mnuNewGame = new System.Windows.Forms.MenuItem();
            this.menuItem5 = new System.Windows.Forms.MenuItem();
            this.mnuAbout = new System.Windows.Forms.MenuItem();
            this.pbGameBoard = new System.Windows.Forms.PictureBox();
            this.lblStat = new System.Windows.Forms.Label();
            this.tmr = new System.Windows.Forms.Timer();
            this.pbResult = new System.Windows.Forms.PictureBox();
            this.ilPicturesUsed = new System.Windows.Forms.ImageList();
            this.pnInfo = new System.Windows.Forms.Panel();
            // 
            // mainMenu1
            // 
            this.mainMenu1.MenuItems.Add(this.mnuNew);
            this.mainMenu1.MenuItems.Add(this.mnuMenu);
            // 
            // mnuNew
            // 
            this.mnuNew.Text = "New";
            this.mnuNew.Click += new System.EventHandler(this.menuItem1_Click);
            // 
            // mnuMenu
            // 
            this.mnuMenu.MenuItems.Add(this.mnuUndo);
            this.mnuMenu.MenuItems.Add(this.mnuNewGame);
            this.mnuMenu.MenuItems.Add(this.menuItem5);
            this.mnuMenu.MenuItems.Add(this.mnuAbout);
            this.mnuMenu.Text = "Menu";
            // 
            // mnuUndo
            // 
            this.mnuUndo.Enabled = false;
            this.mnuUndo.Text = "Undo";
            this.mnuUndo.Click += new System.EventHandler(this.mnuUndo_Click);
            // 
            // mnuNewGame
            // 
            this.mnuNewGame.Text = "New game";
            this.mnuNewGame.Click += new System.EventHandler(this.mnuNewGame_Click);
            // 
            // menuItem5
            // 
            this.menuItem5.Text = "-";
            // 
            // mnuAbout
            // 
            this.mnuAbout.Text = "About";
            this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click);
            // 
            // pbGameBoard
            // 
            this.pbGameBoard.Location = new System.Drawing.Point(0, 0);
            this.pbGameBoard.Size = new System.Drawing.Size(176, 140);
            // 
            // lblStat
            // 
            this.lblStat.Font = new System.Drawing.Font("Nina", 8F, System.Drawing.FontStyle.Regular);
            this.lblStat.Location = new System.Drawing.Point(24, 4);
            this.lblStat.Size = new System.Drawing.Size(145, 30);
            this.lblStat.Text = "Time elapsed: {0:hh\':\'mm\':\'ss}; Movements remaining: {1} ";
            // 
            // tmr
            // 
            this.tmr.Interval = 1000;
            this.tmr.Tick += new System.EventHandler(this.tmr_Tick);
            // 
            // pbResult
            // 
            this.pbResult.Location = new System.Drawing.Point(6, 8);
            this.pbResult.Size = new System.Drawing.Size(16, 16);
            this.pbResult.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
            this.ilPicturesUsed.Images.Clear();
            this.ilPicturesUsed.Images.Add(((System.Drawing.Image)(resources.GetObject("resource"))));
            this.ilPicturesUsed.Images.Add(((System.Drawing.Image)(resources.GetObject("resource1"))));
            this.ilPicturesUsed.Images.Add(((System.Drawing.Image)(resources.GetObject("resource2"))));
            this.ilPicturesUsed.Images.Add(((System.Drawing.Image)(resources.GetObject("resource3"))));
            // 
            // pnInfo
            // 
            this.pnInfo.Controls.Add(this.pbResult);
            this.pnInfo.Controls.Add(this.lblStat);
            this.pnInfo.Location = new System.Drawing.Point(0, 146);
            this.pnInfo.Size = new System.Drawing.Size(174, 33);
            // 
            // FormMain
            // 
            this.ClientSize = new System.Drawing.Size(176, 180);
            this.Controls.Add(this.pbGameBoard);
            this.Controls.Add(this.pnInfo);
            this.Font = new System.Drawing.Font("Nina", 11F, System.Drawing.FontStyle.Regular);
            this.Menu = this.mainMenu1;
            this.Text = "Hanoi";
            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.FormMain_KeyUp);

        }

        #endregion

        private void menuItem1_Click(object sender, EventArgs e)
        {
            StartNewGame();
        }

        private void FormMain_KeyUp(object sender, KeyEventArgs e)
        {
            int value = GetValue(e.KeyValue);

            if (value >= 0 && value < 3 && !gameLogic.IsFinished())
                if (!_selected)
                    SelectFrom(value);
                else
                    SelectTo(value);

            _selected = !_selected;
        }

        IGame gameRules;
        GameUI gameUi;
        HanoiGame gameLogic;
        bool _selected;
        int _selectedColumnIndex;
        Form _caller;

        private void SelectTo(int value)
        {
            int from = _selectedColumnIndex;
            int to = value;
            PerformMove(from, to);
        }

        private void PerformMove(int from, int to)
        {
            try
            {
                gameLogic.Move(from, to);
                lblStat.Text = string.Format("From column {0} to column {1}. Moves remaining: {2}", _selectedColumnIndex + 1, to + 1, gameLogic.Moves);
                pbResult.Image = Hanoi.Properties.Resources.MoveAccepted;
            }
            catch (Exception ex)
            {
                lblStat.Text = ex.Message;
                pbResult.Image = Hanoi.Properties.Resources.MoveInvalid;
            }
            gameUi.Refresh();
            PaintGame();
        }

        private void SelectFrom(int value)
        {
            if (gameLogic.HasAny(value))
            {
                _selectedColumnIndex = value;
                lblStat.Text = string.Format("From column {0} ", _selectedColumnIndex + 1);
                gameUi.SelectFrom(value);
                PaintGame();
            }
            else
            {
                gameUi.Refresh();
                PaintGame();
                lblStat.Text = string.Format("There is not any disk in column {0}.", value + 1);
                pbResult.Image = Hanoi.Properties.Resources.MoveInvalid;
                _selectedColumnIndex = -1;
                _selected = !_selected;
            }
        }

        private int GetValue(int keys)
        {
            switch (keys)
            {
                case 49:
                    return 0;
                case 50:
                    return 1;
                case 51:
                    return 2;
                default:
                    return -1;
            }
        }

        private void tmr_Tick(object sender, EventArgs e)
        {
            TimeSpan elapsedTime = DateTime.Now.Subtract(gameLogic.StartTime);

            if (!gameLogic.IsFinished())
                if (gameLogic.TimeControl && gameLogic.TimeAmount.Subtract(elapsedTime) <= new TimeSpan(0,0,0))
                {
                    tmr.Enabled = false;
                    this.Text = string.Format("Hanoi [{0:t}]", gameLogic.TimeAmount.Subtract(elapsedTime));
                    ToLose();
                    return;
                }

            if (gameLogic.TimeControl)
                this.Text = string.Format("Hanoi [{0:t}]", gameLogic.TimeAmount.Subtract(elapsedTime));
            else
                this.Text = string.Format("Hanoi [{0:t}]", elapsedTime);
        }

        private void mnuAbout_Click(object sender, EventArgs e)
        {
            this.tmr.Enabled = false;
            (new Hanoi.Forms.Menu.FormAbout()).ShowDialog();
            this.tmr.Enabled = true;
            this.Show();
        }

        public void StartNewGame()
        {
            gameLogic = new HanoiGame(gameRules);
            gameUi = new GameUI(gameLogic, pbGameBoard.Width, pbGameBoard.Height);

            lblStat.Text = string.Format("Try to move all disk from column {0} to {1}. Moves remaining: {2}",
                gameLogic.Start + 1, gameLogic.End + 1, gameLogic.Moves);

            _selectedColumnIndex = -1;
            _selected = false;
            pbResult.Image = null;
            gameUi.Refresh();
            PaintGame();
            tmr.Enabled = true;
        }

        private void PaintGame()
        {
            //gameUi.Refresh();
            pbGameBoard.Image = gameUi.GetImage();
            mnuUndo.Enabled = gameLogic.CanUndo;

            if (gameLogic.IsWon())
                ToWin();
            else if (gameLogic.IsFinished())
                ToLose();
            tmr.Enabled = !(gameLogic.IsWon() || gameLogic.IsFinished());
        }

        private void ToWin()
        {
            lblStat.Text = string.Format("Winner!!! :)\r\nTime elapsed: {0:t}", DateTime.Now.Subtract(gameLogic.StartTime));
            pbResult.Image = Hanoi.Properties.Resources.Winner;
        }

        private void ToLose()
        {
            lblStat.Text = "You lose!!!\r\nMaybe next time...";
            pbResult.Image = Hanoi.Properties.Resources.Loser;
            tmr.Enabled = false;
        }

        private void mnuNewGame_Click(object sender, EventArgs e)
        {
            this.Close();
            this.Dispose();
        }

        private void mnuUndo_Click(object sender, EventArgs e)
        {
            gameLogic.Undo();
            gameUi.Refresh();
            PaintGame();
            lblStat.Text = "Undone!";
            pbResult.Image = Hanoi.Properties.Resources.MoveAccepted;
            _selected = true;
            _selectedColumnIndex = -1;
        }


    }
}

